import { undoManager, checkSelection } from "../util/Utils.js";
import $ from "jquery";
import Handsontable from "handsontable";
import Raphael from "raphael";
import saveSvgAsPng from "save-svg-as-png";
import { MessageBox } from "element-ui";

export default {
  // 斜线表头
  buildSlash (designer) {
    const { context } = designer;
    if (!checkSelection(context)) {
      return;
    }
    const hot = context.hot;
    const selected = hot.getSelected()[0];
    const rowIndex = selected[0];
    const colIndex = selected[1];
    const cellDef = context.getCell(rowIndex, colIndex);
    let oldCellData = hot.getDataAtCell(rowIndex, colIndex);
    let oldCellDataValue = cellDef.value;
    // 编辑字段
    MessageBox.prompt("斜表头(多个斜表头以|号分隔，为空则生成所有斜表头信息)：", "斜表头定义", {
      confirmButtonText: "确定",
      cancelButtonText: "取消"
    })
      .then(({ value }) => {
        this.buildSlashes(context, rowIndex, colIndex, null, value);
        // hot.render();
        context.isModify = true;
        Handsontable.hooks.run(hot, "afterSelectionEnd", rowIndex, colIndex, selected[2], selected[3]);

        undoManager.add({
          redo: function () {
            oldCellData = hot.getDataAtCell(rowIndex, colIndex);
            oldCellDataValue = cellDef.value;
            this.buildSlashes(context, rowIndex, colIndex, null, value);
            // hot.render();
            context.isModify = true;
            Handsontable.hooks.run(hot, "afterSelectionEnd", rowIndex, colIndex, selected[2], selected[3]);
          },
          undo: function () {
            cellDef.value = oldCellDataValue;
            hot.setDataAtCell(rowIndex, colIndex, oldCellData);
            hot.render();
            context.isModify = true;
            Handsontable.hooks.run(hot, "afterSelectionEnd", rowIndex, colIndex, selected[2], selected[3]);
          }
        });
      })
      .catch(() => {
        this.$message({
          type: "info",
          message: "取消输入"
        });
      });
  },
  buildSlashes (context, rowIndex, colIndex, cellDef, value) {
    this.rowIndex = rowIndex;
    this.colIndex = colIndex;
    this.slashData = [];
    if (value) {
      for (const name of value.split("|")) {
        this.slashData.push(name);
      }
    }
    this.refreshCell(context);
    if (!cellDef) {
      this._buildSlashes();
    }
  },
  refreshCell (context) {
    const hot = context.hot;
    const $td = $(hot.getCell(this.rowIndex, this.colIndex));
    this.rowSpan = $td.prop("rowspan");
    this.colSpan = $td.prop("colspan");
    this.width = -2;
    this.height = -4;
    const rowStart = this.rowIndex;
    const rowEnd = this.rowIndex + this.rowSpan;
    for (let i = rowStart; i < rowEnd; i++) {
      this.height += hot.getRowHeight(i);
    }
    const colStart = this.colIndex;
    const colEnd = this.colIndex + this.colSpan;
    for (let i = colStart; i < colEnd; i++) {
      this.width += hot.getColWidth(i);
    }
  },
  _buildSlashes () {
    const hot = this.context.hot;
    const colStart = this.colIndex;
    const colEnd = this.colIndex + this.colSpan;
    let colWidth = 0;
    for (let i = colStart; i < colEnd; i++) {
      colWidth += hot.getColWidth(i);
    }
    let rowHeight = 0;
    const rowStart = this.rowIndex;
    const rowEnd = this.rowIndex + this.rowSpan;
    for (let i = rowStart; i < rowEnd; i++) {
      rowHeight += hot.getRowHeight(i);
    }
    const dataSize = this.slashData.length;
    let index = 1;
    const slashes = [];
    for (let i = 0; i < this.rowSpan; i++) {
      let height = 0;
      for (let j = 0; j < i; j++) {
        height += hot.getRowHeight(j);
      }
      if (i === 0 || i + 1 < this.rowSpan) {
        height += 8;
      } else {
        height -= 3;
      }
      let itemName = "项目" + index;
      if (dataSize > 0 && index - 1 >= dataSize) {
        break;
      } else {
        if (dataSize > 0) {
          itemName = this.slashData[index - 1];
        }
      }
      const degree = this._computeDegree(colWidth, height);
      // const width = hot.getColWidth(this.colIndex + (this.colSpan - 1));
      const x = parseInt(colWidth - 30);
      slashes.push({
        degree,
        x,
        y: height,
        text: itemName
      });
      index++;
    }
    if (dataSize === 0 || index - 1 < dataSize) {
      let itemName = "项目" + index;
      if (dataSize > 0) {
        itemName = this.slashData[index - 1];
      }
      const degree = this._computeDegree(colWidth, rowHeight);
      let x = colWidth;
      if (this.colSpan > 1) {
        x -= hot.getColWidth(this.colIndex + (this.colSpan - 1));
      } else {
        x -= parseInt(x / 5);
      }
      let y = rowHeight;
      if (this.rowSpan > 1) {
        y -= parseInt(hot.getRowHeight(this.rowIndex + (this.rowSpan - 1)) / 2) + 5;
      } else {
        y -= parseInt(y / 2);
      }
      slashes.push({
        degree,
        x,
        y,
        text: itemName
      });
      index++;
    }
    for (let i = 0; i < this.colSpan; i++) {
      let width = 0;
      for (let j = 0; j < i; j++) {
        width += hot.getColWidth(j);
      }
      let itemName = "项目" + index;
      if (dataSize > 0 && index - 1 >= dataSize) {
        break;
      } else {
        if (dataSize > 0) {
          itemName = this.slashData[index - 1];
        }
      }
      width += 20;
      const degree = this._computeDegree(rowHeight, width);
      const y = rowHeight - 20;
      slashes.push({
        degree,
        x: width,
        y,
        text: itemName
      });
      index++;
    }
    const cellDef = this.context.getCell(this.rowIndex, this.colIndex);
    console.log(cellDef);
    // const cellStyle = cellDef.cellStyle;
    cellDef.value = {
      slashes,
      type: "slash"
    };
  },

  doDraw (context, rowIndex, colIndex) {
    const hot = context.hot;
    const cellDef = context.getCell(rowIndex, colIndex);
    if (rowIndex !== null && rowIndex !== undefined) {
      this.rowIndex = rowIndex;
    }
    if (colIndex !== null && colIndex !== undefined) {
      this.colIndex = colIndex;
    }
    this.refreshCell(context); // 计算width/height
    const slashValue = cellDef.value;
    const cellStyle = cellDef.cellStyle;
    if (!cellStyle.forecolor) {
      cellStyle.forecolor = "#000000";
    }
    let index = 0;
    const td = hot.getCell(this.rowIndex, this.colIndex);
    const $td = $(td);
    $td.empty();
    const container = $(`<div></div>`);
    $td.append(container);
    this.paper = Raphael(container.get(0), this.width, this.height);
    const fontStyle = cellStyle.fontSize + "pt " + (cellStyle.fontFamily ? cellStyle.fontFamily : "宋体");
    const bold = cellStyle.bold ? "bold" : "normal";
    const italic = cellStyle.italic ? "italic" : "normal";
    const underline = cellStyle.underline ? "underline" : "none";
    const textStyle = {
      fill: cellStyle.forecolor,
      font: fontStyle,
      "font-weight": bold,
      "font-style": italic,
      "text-decoration": underline
    };
    const slashes = slashValue.slashes;
    const size = slashes.length;
    for (let i = 0; i < this.rowSpan - 1; i++) {
      if (size > 0 && index >= size) {
        break;
      }
      let h = 0;
      for (let j = 0; j <= i; j++) {
        h += hot.getRowHeight(this.rowIndex + j);
      }
      if (size === 2) h = this.height;
      if (index < size) {
        this.paper.path("M0 0L" + this.width + " " + h).attr({ stroke: cellStyle.forecolor });
      }
      const slash = slashes[index];
      const text = this.paper.text(0, 0, slash.text).attr(textStyle);
      text.attr({
        transform: "T" + slash.x + "," + slash.y + "R" + slash.degree
      });
      index++;
    }

    if (size === 0 || index < size) {
      let h = this.height - hot.getRowHeight(this.rowIndex + (this.rowSpan - 1)) / 3;
      if (index + 1 < size) {
        if (size === 2) h = this.height;
        this.paper.path("M0 0L" + this.width + " " + h).attr({ stroke: cellStyle.forecolor });
      }
      let slash = slashes[index];
      index++;
      let text = this.paper.text(0, 0, slash.text).attr(textStyle);
      text.attr({
        transform: "T" + slash.x + "," + slash.y + "R" + slash.degree
      });
      if (size === 0 || index < size) {
        let w = this.width - hot.getColWidth(this.colIndex + (this.colSpan - 1)) / 3;
        if (index + 1 < size) {
          if (size === 2) w = this.width;
          this.paper.path("M0 0L" + w + " " + this.height).attr({ stroke: cellStyle.forecolor });
        }
        slash = slashes[index];
        index++;
        text = this.paper.text(0, 0, slash.text).attr(textStyle);
        text.attr({
          transform: "T" + slash.x + "," + slash.y + "R" + slash.degree
        });
      }
    }

    for (let i = 0; i < this.colSpan - 1; i++) {
      if (size > 0 && index >= size) {
        break;
      }
      let w = 0;
      for (let j = 0; j <= i; j++) {
        w += hot.getColWidth(this.colIndex + j);
      }
      if (size === 2) w = this.width;
      this.paper.path("M0 0L" + w + " " + this.height).attr({ stroke: cellStyle.forecolor });

      const slash = slashes[index];
      index++;
      const text = this.paper.text(0, 0, slash.text).attr(textStyle);
      text.attr({
        transform: "T" + slash.x + "," + slash.y + "R" + slash.degree
      });
    }
    if (size === 0 || index < size) {
      const slash = slashes[index];
      index++;
      const text = this.paper.text(0, 0, slash.text).attr(textStyle);
      text.attr({
        transform: "T" + slash.x + "," + slash.y + "R" + slash.degree
      });
    }
    const svg = container.children("svg").get(0);
    saveSvgAsPng.svgAsPngUri(svg, { encoderOptions: 1 }, function (base64Data) {
      slashValue.base64Data = base64Data;
    });
  },

  _computeDegree (a, b) {
    const c = Math.sqrt(a * a + b * b);
    const sin = Math.sin(b / c);
    const degree = (180 / Math.PI) * Math.asin(sin);
    return parseInt(degree);
  }
};
